package com.pet.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class MybatisConfig {

	@Bean(name = "stat-filter")
	public StatFilter stat_filter() {
		StatFilter statFilter = new StatFilter();
		statFilter.setMergeSql(true);
		statFilter.setSlowSqlMillis(10000L);
		statFilter.setLogSlowSql(true);
		return statFilter;
	}

	@Bean(name = "log-filter")
	public Slf4jLogFilter log_filter() {
		return new Slf4jLogFilter();
	}

	@Bean(name = "dataSource")
	@Primary
	public DataSource clusterDataSource(
			@Qualifier("jdbcConfig") JdbcConfig dataSourceParam,
			@Qualifier("stat-filter") StatFilter statFilter,
			@Qualifier("log-filter") Slf4jLogFilter slf4jLogFilter) {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(dataSourceParam.getUrl());
		dataSource.setUsername(dataSourceParam.getUsername());
		dataSource.setPassword(dataSourceParam.getPassword());
		dataSource.setName(dataSourceParam.getName());
		dataSource.setInitialSize(dataSourceParam.getInitialSize());
		dataSource.setMinIdle(dataSourceParam.getMinIdle());
		dataSource.setMaxActive(dataSourceParam.getMaxActive());
		dataSource.setMaxWait(dataSourceParam.getMaxWait());
		dataSource.setTimeBetweenEvictionRunsMillis(dataSourceParam.getTimeBetweenEvictionRunsMillis());
		dataSource.setValidationQuery(dataSourceParam.getValidationQuery());
		dataSource.setMinEvictableIdleTimeMillis(dataSourceParam.getMinEvictableIdleTimeMillis());
		dataSource.setTestOnReturn(dataSourceParam.getTestOnReturn());
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(dataSourceParam.getMaxPoolPreparedStatementPerConnectionSize());
		dataSource.setRemoveAbandoned(dataSourceParam.getRemoveAbandoned());
		dataSource.setRemoveAbandonedTimeout(dataSourceParam.getRemoveAbandonedTimeout());
		dataSource.setLogAbandoned(dataSourceParam.getLogAbandoned());

		List<Filter> filters = new ArrayList<Filter>(2);
		filters.add(statFilter);
		filters.add(slf4jLogFilter);
		dataSource.setProxyFilters(filters);
		return dataSource;
	}

	@Bean(name = "transactionManager")
	@Primary
	public DataSourceTransactionManager clusterTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	/**
	 * 根据数据源创建SqlSessionFactory
	 */
	@Bean(name = "sqlSessionFactory")
	@Primary
	public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
		SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
		fb.setDataSource(dataSource);//指定数据源(这个必须有，否则报错)
		fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mappers/**/*Mapper.xml"));//指定xml文件位置
		fb.setConfigLocation(new DefaultResourceLoader().getResource("classpath:/mybatis/mybatis-config.xml"));//指定xml文件位置
		return fb.getObject();
	}

}